package com.gjt.serverSocket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Logger;

/**
 *
 */
public class Integen {
    private static int DEFAUPT_PORT = 1919;
    private static Logger logger = Logger.getLogger("IntegenLog");

    public static void main(String[] args) {

        int port;

        try {
            port = Integer.parseInt(args[0]);
        } catch (RuntimeException e) {
            System.out.println(e.getMessage());
            port = DEFAUPT_PORT;
        }

        System.out.println("监听连接的端口是：" + port);

        ServerSocketChannel serverSocketChannel;
        Selector selector;

        try {
            serverSocketChannel = ServerSocketChannel.open();
            if (!serverSocketChannel.isOpen()) {
                logger.warning("通道没有打开");
                return;
            }

            ServerSocket socket = serverSocketChannel.socket();
            socket.bind(new InetSocketAddress(port));
            serverSocketChannel.configureBlocking(false);

            selector = Selector.open();
            if (!selector.isOpen()) {
                logger.warning("通道没有打开");
                return;
            }

            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        while (true) {
            try {
                selector.select();
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }

            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();

                try {
                    if (key.isAcceptable()) {
                        ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                        SocketChannel client = channel.accept();

                        System.out.println("来自" + client.getRemoteAddress() + "的连接");
                        client.configureBlocking(false);

                        client.register(selector, SelectionKey.OP_WRITE);
                        ByteBuffer outPut = ByteBuffer.allocateDirect(4);
                        outPut.putInt(0);

                        // 翻转缓冲区 position 为0 ； limit 为 元素的末尾
                        outPut.flip();

                        key.attach(outPut);
                    }else if(key.isWritable()){
                        SocketChannel client = (SocketChannel)key.channel();
                        ByteBuffer outPut = (ByteBuffer)key.attachment();

                        if(outPut != null && !outPut.hasRemaining()){
                            //只重置位置 不重置limit
                            outPut.rewind();

                            // 上界为当前位置    位置为0
//                            outPut.flip();

                            // compact 未读取的数据整体前移，位置 为0，limit为未读取数据的末尾
//                            outPut.compact();


                            /**
                             * 注意： 为什么使用ByteBuffer 而不使用IntBuffer ,因为IntBuffer 只是ByteBuffer 的一个视图  SocketChannel 只有读写 ByteBuffer 的方法
                             */
                            int value= outPut.getInt();

                            // 位置设置为0 上界为容量
                            outPut.clear();
                            outPut.putInt(value + 1);
                            outPut.flip();
                        }
                        client.write(outPut);
                    }

                } catch (IOException e) {
                    key.cancel();
                    try{
                        key.channel().close();
                    }catch (IOException ex){

                    }
                }
            }
        }
    }


}
